﻿/*
=======================================================
    Department【部门】
=======================================================
*/

namespace Services
{
    public interface IDepartmentLogic : ILogic<DepartmentModel, DepartmentFilterModel>
    {
        int UpdateIsDelete(bool flag, params int[] ids);
    }


    public class DepartmentLogic : BaseLogic<DepartmentModel, DepartmentFilterModel, Department, IDepartmentRepository, IDepartmentMapping, IDepartmentService>, IDepartmentLogic
    {
        private readonly IDepartmentUserRepository _IDepartmentUserRepository;
        private readonly IUsingWireropeRepository _IUsingWireropeRepository;
        private readonly IDataDepartmentRepository _IDataDepartmentRepository;
        private readonly IRoleDepartmentRepository _IRoleDepartmentRepository;
        private readonly IRoleRepository _IRoleRepository;

        public DepartmentLogic(ICurrentUser currentUser, IDepartmentRepository repository, IDepartmentMapping mapping, IDepartmentService service,
            IDepartmentUserRepository iDepartmentUserRepository, IUsingWireropeRepository iUsingWireropeRepository, IDataDepartmentRepository iDataDepartmentRepository,
            IRoleDepartmentRepository iRoleDepartmentRepository, IRoleRepository iRoleRepository)
            : base(currentUser, repository, mapping, service)
        {
            _IDepartmentUserRepository = iDepartmentUserRepository;
            _IUsingWireropeRepository = iUsingWireropeRepository;
            _IDataDepartmentRepository = iDataDepartmentRepository;
            _IRoleDepartmentRepository = iRoleDepartmentRepository;
            _IRoleRepository = iRoleRepository;
        }

        #region 启用/禁用  UpdateIsDelete
        public int UpdateIsDelete(bool flag, params int[] ids)
        {
            return _repository.UpdateIsDelete(flag, ids);
        }
        #endregion

        #region GetAll
        public override List<DepartmentModel> GetAll(string orderBy = null)
        {
            var list = base.GetAll(orderBy);

            //得到所有部门中的用户
            var departmentUsers = _IDepartmentUserRepository.GetAll();

            //获取当前用户应该有的数据权限范围
            var (isAll, dataPermissionDepartmentIDs) = _currentUser.CurrentUserInfo.LoginUserRoleDepartment;

            //获取所有部门设置的数据权限
            List<DataDepartment> departmentDataPermissions = _IDataDepartmentRepository.GetDataDepartmentsByDataIDs(DataDepartment_Type.部门, list.Select(x => x.DepartmentID).ToArray());

            //循环所有的数据，每一条数据单独处理
            foreach (var item in list)
            {
                //处理用户数量
                item.UserCount = departmentUsers.Count(x => x.DepartmentID == item.DepartmentID);

                //获取当前循环这条部门数据的所设置的数据权限
                var _currentDataPermissions = departmentDataPermissions.Where(x => x.DataID == item.DepartmentID).Select(x => x.DepartmentID).ToList();

                //设置每一条数据的数据权限的部门名称
                if (_currentDataPermissions.Any(x => x == Gx._NO_DATA_PERMISSION_VALUE))
                {
                    item.SelectDepartmentNames = new List<string>() { "不限" };
                }
                else
                {
                    item.SelectDepartmentNames = list.Where(x => _currentDataPermissions.Contains(x.DepartmentID)).Select(x => x.Name).ToList();
                }

                //如果当前用户是有全部数据权限，则所有数据都会设置为true
                if (isAll == true)
                {
                    item.HasPermission = true;
                }
                else
                {
                    //如果当前循环的这条部门数据item，在DataDepartment中设置的为-1（不限），则也设置true
                    if (_currentDataPermissions.Any(x => x == Gx._NO_DATA_PERMISSION_VALUE))
                    {
                        item.HasPermission = true;
                    }
                    else
                    {
                        //获取当前循环这条部门数据item在DataDepartment中设置的所有DepartmentID，即当前这条数据设置的数据归属
                        var curDataDepartmentIDs = _currentDataPermissions;

                        //如果这条数据的数据归属部门IDs与当前用户的数据权限范围，求交集有数据，则设置为ture，否为设置为false
                        if (curDataDepartmentIDs.Intersect(dataPermissionDepartmentIDs).Any())
                        {
                            item.HasPermission = true;
                        }
                        else
                        {
                            item.HasPermission = false;
                        }
                    }
                }

                if (item.ParentID == 0)
                {
                    continue;
                };

                //处理上级部门信息
                var parent = list.FirstOrDefault(x => x.DepartmentID == item.ParentID);
                item.ParentName = parent?.Name;
                item.ParentType = parent?.Type;
            }

            return list;
        }
        #endregion

        #region GetByID
        public override DepartmentModel GetByID(int id)
        {
            var item = base.GetByID(id);
            item.SelectDepartmentIDs = _IDataDepartmentRepository.GetDataDepartmentsByDataIDs(DataDepartment_Type.部门, id).Select(x => x.DepartmentID).ToList();

            if (item.ParentID == 0)
            {
                return item;
            }

            //处理上级部门信息
            var parentItem = _repository.GetParent(item.ParentID);
            item.ParentName = parentItem?.Name;
            item.ParentType = parentItem?.Type;

            return item;
        }
        #endregion

        #region Insert
        public override DepartmentModel Insert(DepartmentModel model)
        {
            var res = base.Insert(model);
            var (isAll, roleIDs) = _IRoleRepository.GetCurrentUserRoleIDsByTypeWithDepartment();
            if (isAll == false)
            {
                _IRoleDepartmentRepository.BatchInsert(roleIDs.Select(x => new RoleDepartment
                {
                    GroupInfoID = _currentUser.CurrentUserInfo.LoginTypeID,
                    RoleID = x,
                    DepartmentID = res.DepartmentID,
                }).ToList());
            }
            _IDataDepartmentRepository.InsertByDataID(DataDepartment_Type.部门, res.DepartmentID, model.SelectDepartmentIDs.ToArray());
            return res;
        }
        #endregion

        #region Update
        public override int Update(DepartmentModel model)
        {
            var entity = _repository.GetByID(model.DepartmentID);
            if (model.Type == (int)Department_Type.普通 && entity.Type == (int)Department_Type.矿山)
            {
                var where = Expressionable.Create<UsingWirerope>();
                where = where.And(x => x.DepartmentID == model.DepartmentID);
                var cnt = _IUsingWireropeRepository.GetCount(where);
                if (cnt > 0)
                {
                    throw new CustomException("该矿山已被使用，不能修改其类型！");
                }
            }
            _IDataDepartmentRepository.UpdateByDataID(DataDepartment_Type.部门, model.DepartmentID, model.SelectDepartmentIDs.ToArray());
            return base.Update(model);
        }
        #endregion

        #region Delete
        public override int Delete(int id)
        {
            var entity = _repository.GetByID(id);
            if (entity.ParentID == 0)
            {
                throw new CustomException("不能删除顶级部门！");
            }

            var childrenCount = _repository.GetChildrenCount(id);
            if (childrenCount > 0)
            {
                throw new CustomException("该部门下还有子部门，不能删除！");
            }

            var userCount = _IDepartmentUserRepository.GetCountByDepartment(id);
            if (userCount > 0)
            {
                throw new CustomException("该部门下还有用户，不能删除！");
            }

            var roleCount = _IRoleDepartmentRepository.GetCountByDepartment(id);
            if (roleCount > 0)
            {
                throw new CustomException("该部门被角色模块使用，不能删除！");
            }

            var dataCount = _IDataDepartmentRepository.GetCountByDepartment(id);
            if (dataCount > 0)
            {
                throw new CustomException("该部门被数据归属使用，不能删除！");
            }

            _IDataDepartmentRepository.DeleteByDataID(DataDepartment_Type.部门, id);
            return base.Delete(id);
        }
        #endregion
    }
}
